// Copyright (c) 2011 Blue Onion Software, All rights reserved
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Hosting;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using BlueOnionSoftware.Bloget.Properties;

namespace BlueOnionSoftware.Bloget
{
    internal class AdminView : View
    {
        private readonly TextBox _title = new TextBox();
        private readonly TextBox _description = new TextBox();
        private readonly TextBox _link = new TextBox();
        private readonly TextBox _firstName = new TextBox();
        private readonly TextBox _lastName = new TextBox();

        private readonly TextBox _language = new TextBox();
        private readonly TextBox _copyright = new TextBox();
        private readonly TextBox _webMaster = new TextBox();
        private readonly TextBox _author = new TextBox();
        private readonly TextBox _rssChannelImage = new TextBox();
        private readonly TextBox _rssFooter = new TextBox();
        private readonly TextBox _rssEntriesPerFeed = new TextBox();

        private readonly TextBox _itemsPerPage = new TextBox();
        private readonly DropDownList _timeZone = new DropDownList();
        private readonly TextBox _editorWidth = new TextBox();
        private readonly TextBox _editorHeight = new TextBox();

        private readonly CheckBox _allowComments = new CheckBox();
        private readonly TextBox _expireComments = new TextBox();
        private readonly TextBox _maximumComments = new TextBox();
        private readonly TextBox _maximumPingBacks = new TextBox();

        private readonly CheckBox _emailComments = new CheckBox();
        private readonly CheckBox _emailPingbacks = new CheckBox();
        private readonly TextBox _emailFrom = new TextBox();
        private readonly TextBox _emailTo = new TextBox();
        private readonly Button _testEmail = new Button();

        private readonly CheckBox _enableRealSimpleDiscovery = new CheckBox();
        private readonly CheckBox _enableMetaWebLogApi = new CheckBox();
        private readonly CheckBox _enableAutoPingBack = new CheckBox();
        private readonly CheckBox _enablePingBackService = new CheckBox();
        private readonly TextBox _expirePingBacks = new TextBox();

        private readonly TextBox _imageFolder = new TextBox();
        private readonly TextBox _imageUrl = new TextBox();

        private readonly FileUpload _upload = new FileUpload();
        private readonly Button _downloadBackup = new Button();
        private readonly Button _save = new Button();

        private bool _disposed;

        private const int MaxTextBoxLength = 200;
        private const int MaxPasswordLength = 30;

        private static readonly CultureInfo CurrentCulture = CultureInfo.CurrentCulture;
        private static readonly CultureInfo InvariantCulture = CultureInfo.InvariantCulture;

        internal AdminView(BlogetBlog blogetBlog)
            : base(blogetBlog)
        {
            _title.ID = "title";
            _description.ID = "description";
            _link.ID = "link";
            _firstName.ID = "firstName";
            _lastName.ID = "lastName";

            _language.ID = "language";
            _copyright.ID = "copyright";
            _webMaster.ID = "webMaster";
            _author.ID = "author";
            _rssChannelImage.ID = "rssChannelImage";
            _rssFooter.ID = "rssFooter";
            _rssEntriesPerFeed.ID = "rssEntriesPerFeed";

            _itemsPerPage.ID = "itemsPerPage";
            _timeZone.ID = "timeZone";
            _editorWidth.ID = "editorWidth";
            _editorHeight.ID = "editorHeight";

            _allowComments.ID = "allowComments";
            _expireComments.ID = "expireComments";
            _maximumComments.ID = "maximumComments";
            _maximumPingBacks.ID = "maximumPingBacks";

            _emailComments.ID = "emailComments";
            _emailPingbacks.ID = "emailPingbacks";
            _emailFrom.ID = "emailFrom";
            _emailTo.ID = "emailTo";
            _testEmail.ID = "testEmail";

            _enableRealSimpleDiscovery.ID = "enableRSD";
            _enableMetaWebLogApi.ID = "enableMetaWebLogApi";
            _expirePingBacks.ID = "expirePingBacks";
            _enableAutoPingBack.ID = "enableAutoPingBack";
            _enablePingBackService.ID = "enablePingBackService";

            _imageFolder.ID = "imageFolder";
            _imageUrl.ID = "imageUrl";

            _upload.ID = "upload";
            _downloadBackup.ID = "downloadBackup";
            _save.ID = "saveButton";
        }

        private void BasicInformationSection()
        {
            Section(Resources.AdminViewBasicInformationSection);

            InputField(Resources.AdminViewTitle, _title, Bloget.Blog.Title, string.Empty, true, null);
            InputField(Resources.AdminViewSubtitle, _description, Bloget.Blog.Description, string.Empty, true, null);
            InputField(Resources.AdminViewBlogLink, _link, Bloget.Blog.Link, Resources.AdminViewBlogLinkTip, true, UrlValidator());

            EndSection();
        }

        private void SyndicationSection()
        {
            Section(Resources.AdminViewSyndicationSection);

            InputField(Resources.AdminViewLanguage, _language, Bloget.Blog.Language, Resources.AdminViewLanguageTip, true,
                       null);

            InputField(Resources.AdminViewCopyright, _copyright, Bloget.Blog.Copyright, Resources.AdminViewCopyrightTip,
                       true, null);

            InputField(Resources.AdminViewWebMaster, _webMaster, Bloget.Blog.Webmaster, Resources.AdminViewWebMasterTip,
                       true,
                       EmailValidator());

            InputField(Resources.AdminViewRssChannelImage, _rssChannelImage, Bloget.Blog.RssChannelImage,
                       Resources.AdminViewRssChannelImageTip, false, UrlValidator());

            InputField(Resources.AdminViewRssFooter, _rssFooter, Bloget.Blog.RssFooter, Resources.AdminViewRssFooterTip,
                       false, null);

            NumericField(Resources.AdminViewPostsPerFeed, _rssEntriesPerFeed,
                         Bloget.Blog.RssEntriesPerFeed.ToString(CurrentCulture),
                         Resources.AdminViewPostsPerFeedTip, false, RangeValidator("1", "100"));

            EndSection();
        }

        private void AppearanceSection()
        {
            Section(Resources.AdminViewAppearanceSection);

            NumericField(Resources.AdminViewItemsPerPage, _itemsPerPage,
                         Bloget.Blog.PostsPerPage.ToString(CurrentCulture),
                         Resources.AdminViewItemsPerPageTip, true, RangeValidator("1", "100"));

            TimeZoneField(_timeZone);

            NumericField(Resources.AdminViewEditorWidth, _editorWidth, Bloget.Blog.EditorWidth.ToString(CurrentCulture),
                         Resources.AdminViewEditorWidthTip, true, RangeValidator("100", "5000"));

            NumericField(Resources.AdminViewEditorHeight, _editorHeight,
                         Bloget.Blog.EditorHeight.ToString(CurrentCulture),
                         Resources.AdminViewEditorHeightTip, true, RangeValidator("100", "5000"));

            EndSection();
        }

        private void CommentSection()
        {
            Section(Resources.AdminViewCommentsSection);

            CheckBoxField(Resources.AdminViewAllowComments, _allowComments, Bloget.Blog.AllowComments,
                          Resources.AdminViewAllowCommentsTip);

            NumericField(Resources.AdminViewExpireComments, _expireComments,
                         Bloget.Blog.ExpireComments.ToString(CurrentCulture),
                         Resources.AdminViewExpireCommentsTip, true,
                         RangeValidator("1", "999"));

            NumericField(Resources.AdminViewCommentsPerPost, _maximumComments,
                         Bloget.Blog.MaximumCommentsPerPost.ToString(CurrentCulture),
                         Resources.AdminViewCommentsPerPostTip, true, RangeValidator("1", "999"));

            EndSection();
        }

        private void NotificationsSection()
        {
            Section(Resources.AdminViewNotificationsSection);

            CheckBoxField(Resources.AdminViewNotifyComments, _emailComments, Bloget.Blog.EmailComments,
                          Resources.AdminViewNotifyCommentsTip);

            CheckBoxField(Resources.AdminViewNotifyPingBacks, _emailPingbacks, Bloget.Blog.EmailPingbacks,
                          Resources.AdminViewNotifyPingBacksTip);

            InputField(Resources.AdminViewNotifyToAddress, _emailTo, Bloget.Blog.EmailTo,
                       Resources.AdminViewNotifyToAddressTip, false, EmailValidator());

            Label(string.Empty, _testEmail.ID);
            _testEmail.Text = Resources.AdminViewNotifyTestMessageButton;
            _testEmail.Click += SendTestEmailClick;
            Bloget.Controls.Add(_testEmail);

            EndSection();
        }

        private void ServicesSection()
        {
            Section(Resources.AdminViewServicesSection);

            CheckBoxField(Resources.AdminViewServicesRsd, _enableRealSimpleDiscovery,
                          Bloget.Blog.EnableRealSimpleDiscovery,
                          Resources.AdminViewServicesRsdTip);

            CheckBoxField(Resources.AdminViewServicesMetaWeblogApi, _enableMetaWebLogApi, Bloget.Blog.EnableMetaWeblogApi,
                          Resources.AdminViewServicesMetaWeblogApiTip);

            CheckBoxField(Resources.AdminViewServicesSendPingbacks, _enableAutoPingBack, Bloget.Blog.EnableAutoPingBack,
                          Resources.AdminViewServicesSendPingbacksTips);

            CheckBoxField(Resources.AdminViewServicesAcceptPingBacks, _enablePingBackService,
                          Bloget.Blog.EnablePingBackService,
                          Resources.AdminViewServicesAcceptPingBacksTip);

            NumericField(Resources.AdminViewServicesExpirePingBacks, _expirePingBacks,
                         Bloget.Blog.ExpirePingBacks.ToString(CurrentCulture),
                         Resources.AdminViewServicesExpirePingBacksTip,
                         true, RangeValidator("1", "999"));

            NumericField(Resources.AdminViewServicesMaximumPingBacks, _maximumPingBacks,
                         Bloget.Blog.MaximumPingsBacksPerPost.ToString(CurrentCulture),
                         Resources.AdminViewServicesMaximumPingBacksTip,
                         true, RangeValidator("1", "999"));

            EndSection();
        }

        private void ImagesSection()
        {
            Section(Resources.AdminViewImagesSection);

            InputField(Resources.AdminViewImageFolder, _imageFolder, Bloget.Blog.ImageFolder,
                       Resources.AdminViewImageFolderTip,
                       false, VirtualPathValidator());

            InputField(Resources.AdminViewImageUrl, _imageUrl, Bloget.Blog.ImageUrl,
                       Resources.AdminViewImageUrlTip,
                       false, UrlValidator());

            EndSection();
        }

        private void ImportExportSection()
        {
            Section(Resources.AdminViewImportExportSection);
            var export = new Button
            {
                ID = "export",
                Text = Resources.AdminViewImportExportDownloadButton,
                ToolTip = Resources.AdminViewImportExportDownloadButtonTip
            };
            export.Click += ExportDataClick;
            Label(Resources.AdminViewImportExportExportLabel, export.ID);
            Bloget.Controls.Add(export);
            Bloget.WriteLine("<br />");

            Label(Resources.AdminViewImportExportImportLabel, _upload.ID);
            _upload.CssClass = RootClassId() + "-input";
            Bloget.Controls.Add(_upload);
            Bloget.Write("&nbsp;");
            var import = new Button
            {
                Text = Resources.AdminViewImportExportImportButton,
                ToolTip = Resources.AdminViewImportExportImportButtonTip
            };
            import.Click += ImportDataClick;
            import.CssClass = RootClassId() + "-input";
            Bloget.Controls.Add(import);
            Bloget.WriteLine("<br/>");

            Label(string.Empty, _downloadBackup.ID);
            _downloadBackup.Text = Resources.AdminViewImportExportBackupText;
            _downloadBackup.ToolTip = Resources.AdminViewImportExportBackupToolTip;
            _downloadBackup.Click += DownloadBackupClick;
            Bloget.Controls.Add(_downloadBackup);

            EndSection();
        }

        protected override string RootClassId()
        {
            return "admin-view";
        }

        protected override void ShowView()
        {
            if (Bloget.IsAdministrator == false)
            {
                var passwordForm = new PasswordView(Bloget);
                passwordForm.Show();
                return;
            }

            Bloget.Page.MaintainScrollPositionOnPostBack = true;
            MainMenu.ShowMenu(Bloget);

            BasicInformationSection();
            SyndicationSection();
            AppearanceSection();
            CommentSection();
            NotificationsSection();
            ServicesSection();
            ImagesSection();
            ImportExportSection();

            var validationSummary = new ValidationSummary {HeaderText = Resources.AdminViewSummaryValidation};
            Bloget.WriteLine("<p>");
            Bloget.Controls.Add(validationSummary);
            Bloget.WriteLine("</p>");

            _save.Text = Text.ButtonPadding(Resources.AdminViewSaveButton);
            _save.Click += SaveAdminClick;
            Bloget.Controls.Add(_save);
            Bloget.WriteLine("&nbsp;");

            var cancel = new Button {Text = Text.ButtonPadding(Resources.AdminViewDoneButton)};
            cancel.Style.Add("color", "red");
            cancel.CausesValidation = false;
            cancel.Click += (s, e) => Bloget.Redirect(Bloget.BuildQueryString(Mode.Blog, null, 0, null, null, default(DateTime), null));
            Bloget.Controls.Add(cancel);

            Bloget.Load += OnLoad;
        }

        private void OnLoad(object sender, EventArgs ea)
        {
            Bloget.Page.Form.DefaultButton = _save.UniqueID;
            Bloget.Load -= OnLoad;
        }

        private static CustomValidator UrlValidator()
        {
            var urlValidator = new CustomValidator();
            urlValidator.ServerValidate += UrlValidate;
            urlValidator.Text = " * ";
            return urlValidator;
        }

        private static void UrlValidate(object sender, ServerValidateEventArgs ea)
        {
            // Empty is a valid string in this case.
            if (ea != null)
            {
                ea.IsValid = Uri.IsWellFormedUriString(ea.Value, UriKind.Absolute) ? true : string.IsNullOrEmpty(ea.Value);
            }
        }

        private static CustomValidator VirtualPathValidator()
        {
            var virtualPathValidator = new CustomValidator();
            virtualPathValidator.ServerValidate += VirtualPathValidate;
            virtualPathValidator.Text = Resources.AdminViewVirtualPathValidator;
            virtualPathValidator.ToolTip = Resources.AdminViewVirtualPathValidatorTip;
            return virtualPathValidator;
        }

        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private static void VirtualPathValidate(object sender, ServerValidateEventArgs ea)
        {
            if (ea != null)
            {
                try
                {
                    HostingEnvironment.MapPath(ea.Value);
                    ea.IsValid = true;
                }

                catch (Exception)
                {
                    ea.IsValid = false;
                }
            }
        }

        internal static CustomValidator EmailValidator()
        {
            var emailValidator = new CustomValidator();
            emailValidator.ServerValidate += EmailValidate;
            emailValidator.Text = " * ";
            return emailValidator;
        }

        private static void EmailValidate(object sender, ServerValidateEventArgs ea)
        {
            // Empty string is valid
            if (ea != null)
            {
                ea.IsValid =
                    Regex.IsMatch(
                        ea.Value,
                        @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")
                        ? true
                        : string.IsNullOrEmpty(ea.Value);
            }
        }

        private static RangeValidator RangeValidator(string minimum, string maximum)
        {
            var rangeValidator = new RangeValidator
            {
                Type = ValidationDataType.Integer,
                MinimumValue = minimum,
                MaximumValue = maximum,
                Text = string.Format(CurrentCulture, " ({0} - {1})", minimum, maximum)
            };
            return rangeValidator;
        }

        [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private void SaveAdminClick(object sender, EventArgs ea)
        {
            if (Bloget.Page.IsValid == false)
            {
                return;
            }

            var blog = new Blog(Bloget.Blog); // copy to protect readers

            if (blog.Title != _title.Text)
            {
                Log.Administration(Bloget, "Title", blog.Title, _title.Text);
                blog.Title = _title.Text;
            }

            if (blog.Description != _description.Text)
            {
                Log.Administration(Bloget, "Description", blog.Description, _description.Text);
                blog.Description = _description.Text;
            }

            if (blog.Link != _link.Text)
            {
                Log.Administration(Bloget, "Link", blog.Link, _link.Text);
                blog.Link = _link.Text;
            }

            if (blog.Language != _language.Text)
            {
                Log.Administration(Bloget, "Language", blog.Language, _language.Text);
                blog.Language = _language.Text;
            }

            if (blog.Copyright != _copyright.Text)
            {
                Log.Administration(Bloget, "Copyright", blog.Copyright, _copyright.Text);
                blog.Copyright = _copyright.Text;
            }

            if (blog.Webmaster != _webMaster.Text)
            {
                Log.Administration(Bloget, "Webmaster", blog.Webmaster, _webMaster.Text);
                blog.Webmaster = _webMaster.Text;
            }

            //if (blog.AuthorEmail != author.Text)
            //{
            //    Log.Administration(bloget, "Author", blog.AuthorEmail, author.Text);
            //    blog.AuthorEmail = author.Text;
            //}

            if (blog.RssChannelImage != _rssChannelImage.Text)
            {
                Log.Administration(Bloget, "RSS Channel Image", blog.RssChannelImage, _rssChannelImage.Text);
                blog.RssChannelImage = _rssChannelImage.Text;
            }

            if (blog.RssFooter != _rssFooter.Text)
            {
                Log.Administration(Bloget, "RSS Footer", blog.RssFooter, _rssFooter.Text);
                blog.RssFooter = _rssFooter.Text;
            }

            var itemsPerFeed = int.Parse(_rssEntriesPerFeed.Text, CurrentCulture);

            if (blog.RssEntriesPerFeed != itemsPerFeed)
            {
                Log.Administration(Bloget, "Rss entries per feed", blog.RssEntriesPerFeed.ToString(InvariantCulture),
                                   itemsPerFeed.ToString(InvariantCulture));
                blog.RssEntriesPerFeed = itemsPerFeed;
            }

            var itemsPerPageCount = int.Parse(_itemsPerPage.Text, CurrentCulture);

            if (blog.PostsPerPage != itemsPerPageCount)
            {
                Log.Administration(Bloget, "Items Per Page", blog.PostsPerPage.ToString(InvariantCulture),
                                   itemsPerPageCount.ToString(InvariantCulture));
                blog.PostsPerPage = itemsPerPageCount;
            }

            var selectedTimeZone = int.Parse(_timeZone.SelectedValue, InvariantCulture);

            if (blog.TimeZone != selectedTimeZone)
            {
                Log.Administration(Bloget, "Timezone", blog.TimeZone.ToString(InvariantCulture),
                                   selectedTimeZone.ToString(InvariantCulture));
                blog.TimeZone = selectedTimeZone;
            }

            var width = int.Parse(_editorWidth.Text, CurrentCulture);

            if (blog.EditorWidth != width)
            {
                Log.Administration(Bloget, "Editor Width", blog.EditorWidth.ToString(InvariantCulture),
                                   width.ToString(InvariantCulture));
                blog.EditorWidth = width;
            }

            var height = int.Parse(_editorHeight.Text, CurrentCulture);

            if (blog.EditorHeight != height)
            {
                Log.Administration(Bloget, "Editor Height", blog.EditorHeight.ToString(InvariantCulture),
                                   height.ToString(InvariantCulture));
                blog.EditorHeight = height;
            }

            if (blog.AllowComments != _allowComments.Checked)
            {
                Log.Administration(Bloget, "Allow Comments", blog.AllowComments.ToString(InvariantCulture),
                                   _allowComments.Checked.ToString(InvariantCulture));
                blog.AllowComments = _allowComments.Checked;
            }

            var expireCommentsCount = int.Parse(_expireComments.Text, CurrentCulture);

            if (blog.ExpireComments != expireCommentsCount)
            {
                Log.Administration(Bloget, "Expire Comments", blog.ExpireComments.ToString(InvariantCulture),
                                   expireCommentsCount.ToString(InvariantCulture));
                blog.ExpireComments = expireCommentsCount;
            }

            var maximumCommentsCount = int.Parse(_maximumComments.Text, CurrentCulture);

            if (blog.MaximumCommentsPerPost != maximumCommentsCount)
            {
                Log.Administration(Bloget, "Maximum Comments Per Post",
                                   blog.MaximumCommentsPerPost.ToString(InvariantCulture),
                                   maximumCommentsCount.ToString(InvariantCulture));
                blog.MaximumCommentsPerPost = maximumCommentsCount;
            }

            if (blog.EmailComments != _emailComments.Checked)
            {
                Log.Administration(Bloget, "Email Comments", blog.EmailComments.ToString(InvariantCulture),
                                   _emailComments.Checked.ToString(InvariantCulture));
                blog.EmailComments = _emailComments.Checked;
            }

            if (blog.EmailPingbacks != _emailPingbacks.Checked)
            {
                Log.Administration(Bloget, "Email Pingbacks", blog.EmailPingbacks.ToString(InvariantCulture),
                                   _emailPingbacks.Checked.ToString(InvariantCulture));
                blog.EmailPingbacks = _emailPingbacks.Checked;
            }

            if (blog.EmailTo != _emailTo.Text)
            {
                Log.Administration(Bloget, "Email To", blog.EmailTo, _emailTo.Text);
                blog.EmailTo = _emailTo.Text;
            }

            if (blog.ImageFolder != _imageFolder.Text)
            {
                Log.Administration(Bloget, "Image Folder", blog.ImageFolder, _imageFolder.Text);
                blog.ImageFolder = _imageFolder.Text;
            }

            if (blog.ImageUrl != _imageUrl.Text)
            {
                Log.Administration(Bloget, "Image Url", blog.ImageUrl, _imageUrl.Text);
                blog.ImageUrl = _imageUrl.Text;
            }

            if (blog.EnableMetaWeblogApi != _enableMetaWebLogApi.Checked)
            {
                Log.Administration(Bloget, "MetaWebLogApi", blog.EnableMetaWeblogApi.ToString(InvariantCulture),
                                   _enableMetaWebLogApi.Checked.ToString(InvariantCulture));
                blog.EnableMetaWeblogApi = _enableMetaWebLogApi.Checked;
            }

            if (blog.EnableAutoPingBack != _enableAutoPingBack.Checked)
            {
                Log.Administration(Bloget, "Auto Pingback", blog.EnableAutoPingBack.ToString(InvariantCulture),
                                   _enableAutoPingBack.Checked.ToString(InvariantCulture));
                blog.EnableAutoPingBack = _enableAutoPingBack.Checked;
            }

            if (blog.EnablePingBackService != _enablePingBackService.Checked)
            {
                Log.Administration(Bloget, "Pingback Service", blog.EnablePingBackService.ToString(InvariantCulture),
                                   _enablePingBackService.Checked.ToString(InvariantCulture));
                blog.EnablePingBackService = _enablePingBackService.Checked;
            }

            if (blog.EnableRealSimpleDiscovery != _enableRealSimpleDiscovery.Checked)
            {
                Log.Administration(Bloget, "RSD", blog.EnableRealSimpleDiscovery.ToString(InvariantCulture),
                                   _enableRealSimpleDiscovery.Checked.ToString(InvariantCulture));
                blog.EnableRealSimpleDiscovery = _enableRealSimpleDiscovery.Checked;
            }

            var expirePingBacksCount = int.Parse(_expirePingBacks.Text, CurrentCulture);

            if (blog.ExpirePingBacks != expirePingBacksCount)
            {
                Log.Administration(Bloget, "Expire Pingbacks", blog.ExpirePingBacks.ToString(InvariantCulture),
                                   expirePingBacksCount.ToString(InvariantCulture));
                blog.ExpirePingBacks = expirePingBacksCount;
            }

            var maximumPingBacksCount = int.Parse(_maximumPingBacks.Text, CurrentCulture);

            if (blog.MaximumPingsBacksPerPost != maximumPingBacksCount)
            {
                Log.Administration(Bloget, "Maximum Pingbacks", blog.MaximumPingsBacksPerPost.ToString(InvariantCulture),
                                   maximumPingBacksCount.ToString(InvariantCulture));
                blog.MaximumPingsBacksPerPost = maximumPingBacksCount;
            }

            blog.Save();
        }

        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void SendTestEmailClick(object sender, EventArgs ea)
        {
            try
            {
                Bloget.SendEmail(_emailTo.Text, Resources.AdminViewTestEmailSubject,
                                 Resources.AdminViewTestEmailMessage);
            }

            catch (Exception ex)
            {
                Log.Exception(Bloget, "SendTestEmailClick", ex);
                Bloget.ErrorPage(ex.Message);
            }
        }

        private void ExportDataClick(object sender, EventArgs ea)
        {
            Log.Administration(Bloget, "Export", string.Empty, string.Empty);
            ExportData();
        }

        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void ImportDataClick(object sender, EventArgs ea)
        {
            try
            {
                if (_upload.HasFile)
                {
                    ImportBlog.Import(Bloget.Blog, _upload.FileContent);
                    Log.Administration(Bloget, "Import", string.Empty, string.Empty);
                }
            }

            catch (Exception ex)
            {
                Log.Exception(Bloget, "ImportDataClick", ex);
            }
        }

        private void DownloadBackupClick(object sender, EventArgs ea)
        {
            BackupData();
        }

        private void Section(string titleArg)
        {
            Bloget.WriteLine(@"<fieldset class=""adminview-section"">");
            Bloget.WriteLine("<legend>" + titleArg + "</legend>");
        }

        private void EndSection()
        {
            Bloget.WriteLine("</fieldset>");
        }

        private void InputField(string textLabel,
                                TextBox textBox,
                                string text,
                                string tooltip,
                                bool required,
                                BaseValidator validator)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textbox");
            }
            textBox.TextMode = TextBoxMode.SingleLine;
            textBox.MaxLength = MaxTextBoxLength;
            textBox.Style.Add(HtmlTextWriterStyle.Width, "25em");
            Input(textLabel, textBox, text, tooltip, required, validator);
        }

#if false
        private void PasswordField(string textLabel,
                                   TextBox textBox,
                                   string text,
                                   string tooltip,
                                   bool required,
                                   BaseValidator validator)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textbox");
            }
            textBox.TextMode = TextBoxMode.Password;
            textBox.MaxLength = MaxPasswordLength;
            textBox.Style.Add(HtmlTextWriterStyle.Width, "10em");
            Input(textLabel, textBox, text, tooltip, required, validator);
        }
#endif

        private void NumericField(string textLabel,
                                  TextBox textBox,
                                  string text,
                                  string tooltip,
                                  bool required,
                                  BaseValidator validator)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textbox");
            }
            textBox.TextMode = TextBoxMode.SingleLine;
            textBox.MaxLength = 8;
            textBox.Style.Add(HtmlTextWriterStyle.Width, "5em");
            Input(textLabel, textBox, text, tooltip, required, validator);
        }

        private void TimeZoneField(ListControl dropDownList)
        {
            if (dropDownList == null)
            {
                throw new ArgumentNullException("dropDownList");
            }
            Label(Resources.AdminViewTimeZone, dropDownList.ID);

            foreach (var offset in Time.TimeOffsets())
            {
                dropDownList.Items.Add(new ListItem(offset.ToString(CurrentCulture), offset.ToString(CurrentCulture)));

                if (offset == Bloget.Blog.TimeZone)
                {
                    dropDownList.SelectedIndex = (_timeZone.Items.Count - 1);
                }
            }

            dropDownList.Style.Add(HtmlTextWriterStyle.Width, MaxPasswordLength.ToString(InvariantCulture));
            Bloget.Controls.Add(dropDownList);

            Bloget.WriteLine(string.Format(CurrentCulture, Resources.AdminViewServerTime, DateTime.UtcNow.ToShortTimeString()));
            Bloget.WriteLine("<br />");
        }

        private void Input(string textLabel,
                           TextBox textBox,
                           string text,
                           string toolTip,
                           bool required,
                           BaseValidator validator)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textbox");
            }
            Label(textLabel, textBox.ID);

            if (required)
            {
                RequiredTextBoxField(textBox, text, toolTip);
            }

            else
            {
                TextBoxField(textBox, text, toolTip);
            }

            if (validator != null)
            {
                validator.ControlToValidate = textBox.ID;
                Bloget.Controls.Add(validator);
            }

            Bloget.WriteLine("<br />");
        }

        private void CheckBoxField(string textLabel,
                                   CheckBox checkBox,
                                   bool check,
                                   string tooltip)
        {
            if (checkBox == null)
            {
                throw new ArgumentNullException("checkBox");
            }
            Label(textLabel, checkBox.ID);
            checkBox.Checked = check;
            checkBox.ToolTip = tooltip;
            Bloget.Controls.Add(checkBox);
            Bloget.WriteLine("<br />");
        }

        private void ExportData()
        {
            using (var xml = new XmlTextWriter(Bloget.Page.Response.OutputStream, Encoding.UTF8))
            {
                xml.Formatting = Formatting.Indented;

                Bloget.Page.Response.Clear();
                Bloget.Page.Response.ContentType = "text/xml";

                var time = DateTime.UtcNow.ToString("s", InvariantCulture);
                time = time.Replace(':', '-');
                var filename = Path.GetFileNameWithoutExtension(Bloget.Blog.DataContext) + "-" + time + ".xml";
                Bloget.Page.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);

                ExportBlog.Export(Bloget.Blog, xml);
                Bloget.Page.Response.Flush();
            }

            Bloget.Page.Response.End();
        }

        private void BackupData()
        {
            Bloget.Page.Response.Clear();
            Bloget.Page.Response.ContentType = "application/zip";

            var time = DateTime.UtcNow.ToString("s", InvariantCulture);
            time = time.Replace(':', '-');
            var filename = Path.GetFileNameWithoutExtension(Bloget.Blog.DataContext) + "-" + time + ".zip";
            Bloget.Page.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);

            Bloget.Blog.Backup(Bloget.Page.Response.OutputStream);
            Bloget.Page.Response.OutputStream.Flush();
            Bloget.Page.Response.End();
        }

        protected override void Dispose(bool managed)
        {
            try
            {
                if (_disposed == false)
                {
                    _disposed = true;

                    if (managed)
                    {
                        _title.Dispose();
                        _description.Dispose();
                        _link.Dispose();
                        _firstName.Dispose();
                        _lastName.Dispose();

                        _language.Dispose();
                        _copyright.Dispose();
                        _webMaster.Dispose();
                        _author.Dispose();
                        _rssChannelImage.Dispose();
                        _rssFooter.Dispose();
                        _rssEntriesPerFeed.Dispose();

                        _itemsPerPage.Dispose();
                        _timeZone.Dispose();
                        _editorWidth.Dispose();
                        _editorHeight.Dispose();

                        _allowComments.Dispose();
                        _expireComments.Dispose();
                        _maximumComments.Dispose();
                        _maximumPingBacks.Dispose();

                        _emailComments.Dispose();
                        _emailPingbacks.Dispose();
                        _emailTo.Dispose();
                        _testEmail.Dispose();

                        _enableRealSimpleDiscovery.Dispose();
                        _enableMetaWebLogApi.Dispose();
                        _enableAutoPingBack.Dispose();
                        _enablePingBackService.Dispose();
                        _expirePingBacks.Dispose();

                        _imageFolder.Dispose();
                        _imageUrl.Dispose();

                        _upload.Dispose();
                        _downloadBackup.Dispose();
                        _save.Dispose();
                    }
                }
            }

            finally
            {
                base.Dispose(managed);
            }
        }
    }
}